#include<iostream>
#include<pthread.h>
#include<vector>
#include<string>
#include<semaphore.h>
using namespace std;
template<typename T>
class RingQueue
{
public:
    RingQueue(int max_cap)
    :max_cap(max_cap),c_step(0),p_step(0)
    {
        sem_init(&data_sem, 0, 0);
        sem_init(&space_sem, 0, max_cap);
        _ringqueue.resize(max_cap);
        pthread_mutex_init(&c, nullptr);
        pthread_mutex_init(&p, nullptr);
    }
    void P(sem_t& t)
    {
        sem_wait(&t);
    }
    void V(sem_t& t)
    {
        sem_post(&t);
    }
    void Push(const T& in)
    {
        P(space_sem);//满了就等着吧
        pthread_mutex_lock(&p);
        _ringqueue[p_step] = in;
        p_step++;
        p_step %= max_cap;
        V(data_sem);
        pthread_mutex_unlock(&p);
    }
    void Pop(T* out)
    {
        P(data_sem);//没了就等着吧
        pthread_mutex_lock(&c);//类似于得到票后竞争锁
        *out = _ringqueue[c_step];
        c_step++;
        c_step %= max_cap;
        V(space_sem);
        pthread_mutex_unlock(&c);
    }
    ~RingQueue()
    {
        sem_destroy(&data_sem);
        sem_destroy(&space_sem);
    }

private:
    vector<T> _ringqueue;
    int max_cap;
    int c_step;
    int p_step;

    sem_t data_sem; //数据量
    sem_t space_sem; //剩余容量

    pthread_mutex_t c, p;
};